package jk.framework.canary.core.engine;

import jk.framework.canary.core.mather.VersionMatcher;
import jk.framework.canary.core.po.RouteContext;
import jk.framework.canary.core.po.CanaryResponse;
import jk.framework.canary.core.po.VersionInfo;
import jk.framework.canary.core.rule.RouteRuleChain;
import jk.framework.canary.core.version.VersionController;

/**
 * @author cuichao
 * 金丝雀发布引擎
 */
public abstract class CanaryPublishEngine {

    protected RouteRuleChain<?> ruleChain;

    protected VersionController versionCtl;

    protected volatile Boolean isAllowWhenNullTargetVersion = Boolean.TRUE;

    protected VersionMatcher matcher;



    public CanaryPublishEngine(RouteRuleChain<?> ruleChain,VersionMatcher matcher) {
        this.ruleChain = ruleChain;
        this.matcher = matcher;
    }

    public <T> CanaryResponse<T> process(RouteContext context, T t){
        validContext();
        return doIsAllow(context,t);
    }


    protected void validContext(){

    }


    protected <T> CanaryResponse<T> doIsAllow(RouteContext context, T t){

        CanaryResponse<T> response = new CanaryResponse<>(t);
        VersionInfo versionInfo = versionCtl.targetVersion();
        if(versionInfo == null){
           response.setAllow(isAllowWhenNullTargetVersion);
           response.setMatchVersion(isAllowWhenNullTargetVersion);
            return response;
        }
        //判断版本匹配
        boolean match = matcher.match(context.getCurrentVersion(), versionInfo.getVersion());
        response.setMatchVersion(match);
        if(!match){
            response.setAllow(false);
            return response;
        }
        //判断路由规则
        boolean isRuleAllow = ruleChain.isAllow(context);
        response.setAllow(isRuleAllow);
        return response;
    }

    public void setVersionCtl(VersionController versionCtl) {
        this.versionCtl = versionCtl;
    }
}
